package com.cgwx.tmservice.netty;

import com.cgwx.commonutils.DataTypeConvertUtils;
import com.cgwx.tmservice.config.CanConfig;
import com.cgwx.tmservice.entity.bean.*;
import com.cgwx.tmservice.utils.ReceiveDataAnalysis;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author GaoWei
 * @Date 2023/8/29 - 15:15
 */

@Slf4j
@Component
public class NettyCanUdpReceiveHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    ExecutorService executor = Executors.newFixedThreadPool(2);

    @Autowired
    private CanConfig canConfig;
    @Autowired
    private ReceiveDataAnalysis receiveDataAnalysis;

//    拼包的遥测帧数据
    private String tmFrame = "";
    private static NettyCanUdpReceiveHandler nettyCanUdpReceiveHandler;

    @PostConstruct
    public void init(){
        nettyCanUdpReceiveHandler = this;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
//        接收UDP中CAN帧的ID
        String canId = "";
//        接收UDP中CAN帧的数据
        String canData = "";

        try {
            ByteBuf byteBuf = packet.content();
//            返回值为当前byteBuf可读取的字节数，新建字节数组
            byte[] bytes = new byte[byteBuf.readableBytes()];
//            读取ByteBuf中的数据。将数据从ByteBuf读取到bytes字节数组中
            byteBuf.readBytes(bytes);
//            将字节数组转换为字符串
            String canReceiveString = Objects.requireNonNull(DataTypeConvertUtils.Byte_to_Hex(bytes)).toUpperCase().replace(" ","");
//            判断CAN帧长是否为13字节
            if (canReceiveString.length() == 26){
//                Can帧ID 26C0~26DB
                canId = canReceiveString.substring(0,10);
                canData = canReceiveString.substring(10);
            }
//            读取配置文件中CAN帧的首帧ID值
            String canFirstFrameId = nettyCanUdpReceiveHandler.canConfig.getCanId().split(",")[0];
//            读取配置文件中的遥测同步字值
            String syncWord = nettyCanUdpReceiveHandler.canConfig.getSyncWord();
//            判断接收到的数据是否为第一帧，如果不是则拼接字符串，得到224字节的遥测数据
            if(canId.equals(canFirstFrameId) && canData.substring(0,4).equals(syncWord)){
                tmFrame = canData;
            }else{
                tmFrame = tmFrame + canData;
            }
//            当遥测帧拼接够224字节后，得到224字节的一帧遥测数据的二进制字符串
            if(tmFrame.length() == 448){
//            将遥测原码存入全局静态变量
//            多通道不知道会不会有问题，可能需要做判断，待定 todo
                TmBeanStatic.TM_FRAME_LOG_REALTIME = tmFrame;
//              开起异步线程执行存储到数据库操作，耗时，必须开启异步线程
                executor.submit(
                    () -> {
                        nettyCanUdpReceiveHandler.receiveDataAnalysis.receiveDataOperate(tmFrame,"can");
                        return null;
                    }
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
